﻿#ifndef VertexPositionNormalTexture_h
#define VertexPositionNormalTexture_h

#include <Defines.h>
#include <CSharpPropertyMethods.h>

// Riccsson includes.
#include <System/RObject.h>
#include <System/RType.h>
#include <System/RString.h>

// XNA includes.
//#include "../../Color.h"
#include "../../Vector2.h"
#include "../../Vector3.h"
#include "../Vertices/IVertexType.h"
#include "../Vertices/VertexElementColor.h"
#include "../Vertices/VertexElement.h"

namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			namespace Graphics
			{
				//[StructLayout(LayoutKind.Sequential, Pack = 1)]
				struct VertexPositionNormalTexture
					: Riccsson::System::Object
					, IVertexType
				{
					public: Vector3 Position;
					public: Vector3 Normal;
					public: Vector2 TextureCoordinate;
					public: static /*readonly*/ VertexDeclaration vertexDeclaration;
					public: VertexPositionNormalTexture(Vector3 position, Vector3 normal, Vector2 textureCoordinate)
					{
						this->Position = position;
						this->Normal = normal;
						this->TextureCoordinate = textureCoordinate;
					}

					//VertexDeclaration IVertexType.VertexDeclaration
					//{
					//	get
					//	{
					//		return VertexDeclaration;
					//	}
					//}

					public: override int GetHashCode()
					{
						// TODO: FIc gethashcode
						return 0;
					}

					public: override GC_PTR<Riccsson::System::string> ToString()
					{
						//return string.Format("{{Position:{0} Normal:{1} TextureCoordinate:{2}}}", new object[] { this->Position, this->Normal, this->TextureCoordinate });
						throw;
					}

					public: override bool Equals(const Riccsson::System::Object* obj)
					{
						if (obj == null)
						{
							return false;
						}
						if (obj->GetType() != Riccsson::System::Object::GetType())
						{
							return false;
						}
						return (this == ((VertexPositionNormalTexture*)obj));
					}

					STATIC(VertexPositionNormalTexture)
					{
						Riccsson::System::Array<VertexElement> elements(3);
						{
							elements.Insert(0, VertexElement(0, VertexElementFormat::Vector3, VertexElementUsage::Position, 0));
							elements.Insert(1, VertexElement(12, VertexElementFormat::Vector3, VertexElementUsage::Normal, 0));
							elements.Insert(2, VertexElement(0x18, VertexElementFormat::Vector2, VertexElementUsage::TextureCoordinate, 0));
						};

						vertexDeclaration = new VertexDeclaration(elements);
					}
				};

				RUN_STATIC(VertexPositionNormalTexture)
					
				bool operator ==(VertexPositionNormalTexture& left, VertexPositionNormalTexture& right)
				{
					return (((left.Position == right.Position) && (left.Normal == right.Normal)) && (left.TextureCoordinate == right.TextureCoordinate));
				}

				bool operator !=(VertexPositionNormalTexture& left, VertexPositionNormalTexture& right)
				{
					return !( (((left.Position == right.Position) && (left.Normal == right.Normal)) && (left.TextureCoordinate == right.TextureCoordinate)) );
				}

			}
		}
	}
}

#endif
